package com.tau.egonetwork.profiles;

import java.util.Map;

public abstract class MainProfile<T extends Comparable<T>> extends Profile<T>
		implements IMainProfile<T> {

	private static final long serialVersionUID = -2866858681110194572L;

	private GroupsList<T> _groupslist = null;

	// analyzed data:
	private boolean analyzedDataExists = false;
	private Map<T, Double> clusteringCoeffients;
	private Map<T, Double> clusteringCoeffientsWithoutRoot;
	private Map<T, Integer> kShellDecomposition;
	private Map<T, Integer> kShellDecompositionWithoutRoot;
	private Map<T, Double> meanShortestPaths;

	public MainProfile(T id, String name) {
		super(id, name);

	}

	@Override
	public GroupsList<T> createGroupsList() {
		_groupslist = new GroupsList<T>();
		return _groupslist;
	}

	@Override
	public GroupsList<T> getGroupsList() {
		return _groupslist;
	}

	public synchronized void storeAnalyzedData(
			Map<T, Double> clusteringCoeffients,
			Map<T, Double> clusteringCoeffientsWithoutRoot,
			Map<T, Integer> kShellDecomposition,
			Map<T, Integer> kShellDecompositionNoRoot,
			Map<T, Double> meanShortestPaths) {

		this.clusteringCoeffients = clusteringCoeffients;
		this.clusteringCoeffientsWithoutRoot = clusteringCoeffientsWithoutRoot;
		this.kShellDecomposition = kShellDecomposition;
		this.kShellDecompositionWithoutRoot = kShellDecompositionNoRoot;
		this.meanShortestPaths = meanShortestPaths;

		analyzedDataExists = true;

	}

	public void analyzedDataOutOfDate() {
		analyzedDataExists = false;
	}

	public boolean getAnalyzedDataExists() {
		return analyzedDataExists;
	}

	public Map<T, Double> getClusteringCoeffients() {
		return clusteringCoeffients;
	}

	public Map<T, Double> getClusteringCoeffientsWithoutRoot() {
		return clusteringCoeffientsWithoutRoot;
	}

	public Map<T, Integer> getkShellDecomposition() {
		return kShellDecomposition;
	}

	public Map<T, Integer> getkShellDecompositionWithoutRoot() {
		return kShellDecompositionWithoutRoot;
	}

	public Map<T, Double> getMeanShortestPaths() {
		return meanShortestPaths;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object clone() {
		MainProfile<T> clonedObject = (MainProfile<T>) super.clone();
		clonedObject._groupslist = null;
		return clonedObject;
	}

	@Override
	public void copyFrom(Profile<T> toCopy) {
		if (toCopy instanceof MainProfile) {
			// copy shallow data:
			super.copyFrom(toCopy);

			// update references to friends and groups
			// (move them to those of toCopy instance):

			if (getFriendsList() == null && toCopy.getFriendsList() != null) {
				// didn't have friends, will have now:
				createFriendsList();
			}
			if (getFriendsList() != null) {
				getFriendsList().clear();
				if (toCopy.getFriendsList() != null) {
					for (Profile<T> p : toCopy.getFriendsList()) {
						getFriendsList().add(p);
					}
				}
			}

			if (_groupslist == null
					&& ((MainProfile<T>) toCopy).getGroupsList() != null) {
				// did not have groups, will have now:
				createGroupsList();
			}
			if (_groupslist != null) {
				_groupslist.clear();
				if (((MainProfile<T>) toCopy).getGroupsList() != null) {
					for (Group<T> g : ((MainProfile<T>) toCopy).getGroupsList()) {
						_groupslist.add(g);
					}
				}
				for (int i = 1; i <= 4; i++) {
					_groupslist.setPriority(i, ((MainProfile<T>) toCopy)
							.getGroupsList().getPriority(i));
				}
			}

			clusteringCoeffients.clear();
			clusteringCoeffientsWithoutRoot.clear();
			kShellDecomposition.clear();
			kShellDecompositionWithoutRoot.clear();
			meanShortestPaths.clear();
			analyzedDataExists = ((MainProfile<T>) toCopy).getAnalyzedDataExists();
			if (analyzedDataExists) {
				//clone clustringCoeffients
				for (T t : ((MainProfile<T>) toCopy).getClusteringCoeffients()
						.keySet()) {
					clusteringCoeffients.put(t, ((MainProfile<T>) toCopy)
							.getClusteringCoeffients().get(t));
				}
				
				//clone clustringCoeffientsNoRoot
				for (T t : ((MainProfile<T>) toCopy).getClusteringCoeffientsWithoutRoot()
						.keySet()) {
					clusteringCoeffientsWithoutRoot.put(t, ((MainProfile<T>) toCopy)
							.getClusteringCoeffientsWithoutRoot().get(t));
				}
				
				//clone kShellDecomposition
				for (T t : ((MainProfile<T>) toCopy).getkShellDecomposition()
						.keySet()) {
					kShellDecomposition.put(t, ((MainProfile<T>) toCopy).getkShellDecomposition().get(t));
				}
				
				//clone kShellDecompositionWithoutRoot
				for (T t : ((MainProfile<T>) toCopy).getkShellDecomposition()
						.keySet()) {
					kShellDecompositionWithoutRoot.put(t, ((MainProfile<T>) toCopy).getkShellDecompositionWithoutRoot().get(t));
				}

				//clone meanShortestPaths
				for (T t : ((MainProfile<T>) toCopy).getMeanShortestPaths()
						.keySet()) {
					meanShortestPaths.put(t, ((MainProfile<T>) toCopy).getMeanShortestPaths().get(t));
				}
			}
		}
	}

}
